//////////////////////////////////////////////
// Quaternion.h
//
//////////////////////////////////////////////

/// Defines / Macros -------------------------

#pragma once

/// Forward decl -----------------------------

namespace nkMaths
{
	class Matrix ;
}

/// Includes ---------------------------------

// nkGraphics
#include "Vector.h"

#include "../Dll/DllDefines.h"

/// Class ------------------------------------
	
namespace nkMaths
{
	class DLL_MATHS_EXPORT Quaternion
	{
		public :
		
			// Constructor, destructor
			Quaternion () noexcept ;
			Quaternion (float x, float y, float z, float w) noexcept ;
			Quaternion (const Vector& axis, float angle) noexcept ;
			Quaternion (const Vector& eulerAngles) noexcept ;
			Quaternion (const Vector& a, const Vector& b) noexcept ;
			Quaternion (const Matrix& mat) noexcept ;
			Quaternion (const Quaternion& other) noexcept ;

			// Getters
			Vector getAsEulerAngles () const ;
			Vector getAsAxisAngle () const ;

			// Setters
			Quaternion& setFromAxisAngle (const Vector& axis, float angle) ;
			Quaternion& setFromEuler (const Vector& angles) ;
			Quaternion& setFromRotationBetween (const Vector& a, const Vector& b) ;
			Quaternion& setFromOrientationMatrix (const Matrix& mat) ;
			Quaternion& setFromTransformationMatrix (const Matrix& mat) ;

			// Transformations
			Vector transform (const Vector& vector) const ;
			Vector& apply (Vector& vector) const ;

			// Utilities
			nkMemory::String toString () const ;
			Quaternion& fromString (nkMemory::StringView str) ;

			// Operators
			// Assignment
			Quaternion& operator= (const Quaternion& other) noexcept ;
			// Mult
			Vector operator* (const Vector& other) const ;
			Quaternion operator* (const Quaternion& other) const ;
			void operator*= (const Quaternion& other) ;
			// Comparison
			bool operator== (const Quaternion& other) const ;

		public :

			// Attributes
			float _x ;
			float _y ;
			float _z ;
			float _w ;
	} ;
}